/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * bocciawii
 * Copyright (C) Grupo de trabajo ULE 2010 <ulewii@googlegroups.com>
 * 
 * teclado is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * teclado is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mensaje.h"


Mensaje::Mensaje(std::string id, FTGLPixmapFont* fuente):
		Elemento(id)
{
	_layout = new FTSimpleLayout();
	_layout->SetLineLength(1000);
	
	_layout->SetFont(fuente);
	_text = "";
	_textSize = _layout->GetFont()->FaceSize();

	_fgColor = new float(3);

	for (int i = 0; i < 3; i++)
		_fgColor[i] = 0.0f;
	
	_posText.ancho = 0;
	_posText.alto = 0;
	_posText.pen_x = 0;
	_posText.pen_y = 0;
}

Mensaje::~Mensaje()
{
	_layout->~FTSimpleLayout();
}

void Mensaje::SetText(std::string text)
{
	_text = text;
}


void Mensaje::SetText(int text)
{
	char *mensaje = new char[10];
	sprintf(mensaje, "%i", text);
	_text = mensaje;
	free (mensaje);
}


void Mensaje::SetText(float text)
{
	char *mensaje = new char[10];
	sprintf(mensaje, "%f", text);
	_text = mensaje;
	free (mensaje);
}

void Mensaje::SetTextAlign(FTGL::TextAlignment align, int line_length)
{
	if (line_length == -1)
		_layout->SetLineLength(line_length);

	_layout->SetAlignment(align);
	
}

void Mensaje::SetSize(int size)
{
//	_layout->GetFont()->FaceSize(size);
	_textSize = size;
}

void Mensaje::SetFGColor(float* color)
{
	for (int i = 0; i < 3; i++)
		_fgColor[i] = color[i];
}

int* Mensaje::GetScreenCoords()
{
	int *espacio = new int(4);

	espacio[0] = _centro_x - GetNeededSpace()[0] / 2 - _spacing;
	espacio[1] = _centro_x + GetNeededSpace()[0] / 2 + _spacing;
	espacio[2] = _centro_y - GetNeededSpace()[1] / 2 - _spacing;
	espacio[3] = _centro_y + GetNeededSpace()[1] / 2 + _spacing;
	return espacio;
}

int* Mensaje::GetNeededSpace()
{
	int *espacio = new int(2);

	_layout->GetFont()->FaceSize(_textSize);
	FTBBox bbox = _layout->BBox(_text.c_str());

	_posText.ancho = bbox.Upper().X() - bbox.Lower().X() + 1; // para evitar errores de float, aunque es una tontería
	_posText.alto = bbox.Upper().Y() - bbox.Lower().Y() + 1;
	
	if (_image != 0 && _image != -1)
		switch (_posImg.alignment)
		{
			case IMG_ALIGN_LEFT:
			case IMG_ALIGN_RIGHT:
				espacio[0] = _posImg.ancho + _spacing + _posText.ancho;
				espacio[1] = _posImg.alto > _posText.alto ? _posImg.alto : _posText.alto;
				break;

			case IMG_ALIGN_ABOVE:
			case IMG_ALIGN_BELOW:
				espacio[0] = _posImg.ancho > _posText.ancho ? _posImg.ancho : _posText.ancho;
				espacio[1] = _posImg.alto + _spacing + _posText.alto;

				break;
		}
	else
	{
		espacio[0] = _posText.ancho;
		espacio[1] = _posText.alto;
	}

	return espacio;
}


void Mensaje::Pack(int centro_x, int centro_y)
{
	int* espacio = GetNeededSpace();

	// Tenemos centros y el espacio máximo necesitado.
	// Pues calculamos, a partir del centro, dependiendo de la alineación de la imagen
	//  etcétera etcétera
	int* centro = new int(2);
	centro[0] = centro_x;
	centro[1] = centro_y;

	_centro_x = centro_x;
	_centro_y = centro_y;
	
	if (_image != 0 && _image != -1)
		switch (_posImg.alignment)
		{
			case IMG_ALIGN_LEFT:
				_posImg.x_inicio = centro[0] - espacio[0] / 2;
				_posImg.y_inicio = centro[1] - _posImg.alto / 2;
				_posImg.x_final = _posImg.x_inicio + _posImg.ancho;
				_posImg.y_final = _posImg.y_inicio + _posImg.alto;

				_posText.pen_x = _posImg.x_final;
				_posText.pen_y = centro[1] - _posText.alto / 2 + _layout->GetFont()->Ascender();
				break;
				
			case IMG_ALIGN_RIGHT:
				_posImg.y_inicio = centro[1] - _posImg.alto / 2;
				_posImg.y_final = _posImg.y_inicio + _posImg.alto;
				_posImg.x_final = centro[0] + espacio[0] / 2;
				_posImg.x_inicio = _posImg.x_final - _posImg.ancho;

				_posText.pen_x = centro[0] - espacio[0] / 2;
				_posText.pen_y = centro[1] - _posText.alto / 2 + _layout->GetFont()->Ascender();
				
				break;

			case IMG_ALIGN_ABOVE:
				_posImg.x_inicio = centro[0] - _posImg.ancho / 2;
				_posImg.y_inicio = centro[1] - espacio[1] / 2;
				_posImg.x_final = _posImg.x_inicio + _posImg.ancho;
				_posImg.y_final = _posImg.y_inicio + _posImg.alto;

				_posText.pen_x = centro[0] - _posText.ancho / 2;
				_posText.pen_y = _posImg.y_final + _layout->GetFont()->Ascender();
				break;
				
			case IMG_ALIGN_BELOW:
				_posText.pen_x = centro[0] - _posText.ancho / 2;
				_posText.pen_y = centro[1] - espacio[1] / 2 + _layout->GetFont()->Ascender();

				_posImg.x_inicio = centro[0] - _posImg.ancho / 2;
				_posImg.y_final = centro[1] + espacio[1] / 2 ;
				_posImg.x_final = _posImg.x_inicio + _posImg.ancho;
				_posImg.y_inicio = _posImg.y_final - _posImg.alto;
				break;
		}
	else
	{
		_posText.pen_x = centro[0] - espacio[0] / 2;
		_posText.pen_y = centro[1] - espacio[1] / 2 + _layout->GetFont()->Ascender();
	}
	
}

void Mensaje::Dibujar()
{
	
	if (_image != 0 && _image != -1)
	{
		glEnable(GL_BLEND);
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, _image); 
		glBegin(GL_QUADS);
			glTexCoord2f(0,0);
			glVertex2i(_posImg.x_inicio, _posImg.y_inicio);
			glTexCoord2f(1,0);
			glVertex2i(_posImg.x_final, _posImg.y_inicio);
			glTexCoord2f(1, 1);
			glVertex2i(_posImg.x_final, _posImg.y_final);
			glTexCoord2f(0, 1);
			glVertex2i(_posImg.x_inicio, _posImg.y_final);
		glEnd();
		glDisable(GL_TEXTURE_2D);
		glDisable(GL_BLEND);
	}

	glColor3f(_fgColor[0], _fgColor[1], _fgColor[2]);
	glRasterPos2i(_posText.pen_x, _posText.pen_y);
	
	_layout->GetFont()->FaceSize(_textSize);
	_layout->Render(_text.c_str());


}
